<template>
	<div class="avatar_uploader">
		<el-avatar :size="size" :src="cropImage"></el-avatar>
		<input ref="upload" type="file" accept=".png,.jpg,.jpeg" @change="handleUploadChange" />
		<template v-if="!hasImage">
			<el-button type="text" icon="el-icon-plus" @click="handleSelectAvatar()"></el-button>
		</template>
		<template v-else>
			<el-button type="text" icon="el-icon-edit" @click="handleSelectAvatar()"></el-button>
		</template>
		<el-dialog title="图片裁剪" :visible.sync="visible" top="0" custom-class="image_cropper_dialog" append-to-body>
			<img ref="cropper" :src="checkedImage" alt="" />
			<div class="img-preview"></div>
			<template slot="footer">
				<el-button size="medium" @click="visible = false">取消</el-button>
				<el-button size="medium" type="primary" :loading="btnLoading" @click="handleSubmitCropper()">确定</el-button>
			</template>
		</el-dialog>
	</div>
</template>

<script>
import Cropper from 'cropperjs';
import 'cropperjs/dist/cropper.css';
import { uploadAttach } from '@/api/system/tbSysAttachment';
export default {
	props: {
		value: { type: String, default: '' },
		src: { type: String, default: '' },
		size: { type: Number, default: 100 }
	},
	data() {
		return {
			btnLoading: false,
			imageId: this.value,
			visible: false,
			cropper: null,
			checkedImage: '',
			cropperImage: ''
		};
	},
	computed: {
		//是否有图片
		hasImage() {
			return !!this.imageId && this.imageId !== '-1';
		},
		cropImage() {
			if (!this.cropperImage) {
				return this.src;
			} else {
				return this.cropperImage;
			}
		}
	},
	watch: {
		value(val) {
			this.imageId = val;
		},
		imageId(val) {
			this.$emit('input', val);
		},
		visible(val) {
			if (!val) return false;
			if (this.cropper) {
				this.cropper.destroy();
			} else {
				this.$nextTick(() => {
					this.initializeCropper();
				});
			}
		}
	},
	methods: {
		//初始化裁剪
		initializeCropper() {
			let that = this;
			this.cropper = new Cropper(this.$refs['cropper'], {
				viewMode: 1,
				aspectRatio: 1,
				autoCropArea: 0.5,
				dragMode: 'move',
				preview: '.img-preview',
				cropBoxResizable: false,
				crop() {}
			});
		},

		//选择图片文件
		handleSelectAvatar() {
			this.$refs['upload'].click();
		},

		//上传选中
		handleUploadChange(e) {
			let file = e.target.files[0];
			this.checkedImage = window.URL.createObjectURL(file);
			this.visible = true;
		},

		//提交裁剪
		handleSubmitCropper() {
			let canvas = this.cropper.getCroppedCanvas();
			let imgBase64 = canvas.toDataURL('image/png');
			let imgFile = this.$base64ToFile(imgBase64, 'avatar.png');
			this.btnLoading = true;
			this.cropperImage = imgBase64;
			this.uploadAttachRequest(imgFile);
		},

		//上传附件请求
		async uploadAttachRequest(file) {
			let formData = new FormData();
			formData.append('file', file);
			try {
				let result = await uploadAttach(formData).then((res) => res.data);
				if (result.code === '0') {
					let datas = this.$detailData(result.data);
					this.imageId = datas.id;
					this.$message.success('上传成功');
				}
			} catch (error) {
				this.$message.error('上传失败');
			}
			this.btnLoading = false;
			this.visible = false;
		}
	}
};
</script>

<style lang="scss" scoped>
.avatar_uploader {
	position: relative;
	border-radius: 50%;
	overflow: hidden;
	flex-shrink: 0;
	font-size: 0;
	input[type='file'] {
		position: absolute;
		top: 50%;
		right: 50%;
		opacity: 0;
		z-index: 0;
		font-size: 86px;
		transform: translate(-50%, -50%);
	}
	&::before {
		position: absolute;
		top: 0;
		left: 0;
		width: 100%;
		height: 100%;
		content: '';
		z-index: 2;
		display: none;
		background-color: rgba(0, 0, 0, 0.5);
	}
	.el-button {
		position: absolute;
		top: 50%;
		left: 50%;
		z-index: 3;
		color: #fff;
		padding: 10px;
		font-size: 20px;
		display: none;
		transform: translate(-50%, -50%);
	}
	&:hover {
		&::before,
		.el-button {
			display: block;
		}
	}
}
</style>
<style lang="scss">
.image_cropper_dialog {
	.el-dialog__body {
		padding: 0;
	}
}
</style>
